package com.cyzy.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cyzy.dto.OrderDriverDto;
import com.cyzy.dto.OrderDto;
import com.cyzy.dto.ResponseDto;
import com.cyzy.dto.TripOrderDto;
import com.cyzy.mapper.OrderMapper;
import com.cyzy.openfeign.DriverOpenFeign;
import com.cyzy.pojo.TripOrder;
import com.cyzy.service.OrderService;
import com.cyzy.utils.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.sql.Timestamp;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, TripOrder> implements OrderService {
    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    @Autowired
    private DriverOpenFeign driverOpenFeign;
    @Autowired
    private RedisUtil redisUtil;

    @Override
    public long createOrder(TripOrder tripOrder) {
//        System.out.println(tripOrder.getCarType().toString());
        //添加订单的车辆类型
        tripOrder.setCarTypes(tripOrder.getCarType().toString());
        System.out.println(tripOrder.getCarPrice());
        String jsonString = JSON.toJSONString(tripOrder.getCarPrice());
        System.out.println(jsonString);
        tripOrder.setCarPrices(jsonString);
        int i = orderMapper.insert(tripOrder);
        Long orderId = tripOrder.getOrderId();
        System.out.println(orderId);
        //将该订单存入redis让司机抢单
        redisTemplate.opsForValue().set(orderId.toString(),String.valueOf(1));
        return orderId;
    }

    @Override
    public ResponseDto orderTaking(TripOrder tripOrder) {
        //订单id
        Long orderId = tripOrder.getOrderId();
        //司机id
        long driverId = tripOrder.getDriverId();



        //如果司机已是接单状态则不能继续接单
        LambdaQueryWrapper<TripOrder> queryWrapper=new LambdaQueryWrapper<TripOrder>()
                .eq(TripOrder::getDriverId,driverId)
                .eq(TripOrder::getOrderStatus,1);

        TripOrder one = orderMapper.selectOne(queryWrapper);
        if(one!=null){
            return ResponseDto.fail("您已在接单中！");
        }

        Long i = redisTemplate.opsForValue().decrement(orderId.toString());
        System.out.println(i);
        if(i==0){
            //删除该订单在redis中的数据
            redisTemplate.delete(orderId.toString());
            System.out.println("在redis中删除该订单，表示该订单已被接单！");
        }
        if(i<0){
            System.out.println("订单已经被抢！");
            return ResponseDto.fail("订单已经被抢！");
        }
        //修改该订单的状态、司机id、订单价格
        LambdaQueryWrapper<TripOrder> wrapper=new LambdaQueryWrapper<TripOrder>()
                .eq(TripOrder::getOrderId,orderId);
        TripOrder order=orderMapper.selectOne(wrapper);
        System.out.println(order);
        order.setDriverId(driverId);
        order.setOrderStatus(1);
        order.setPrice(tripOrder.getPrice());
        int ii = orderMapper.updateById(order);
        if(ii<=0){
            return ResponseDto.fail("修改订单失败！");
        }
        //修改司机的状态为可接单状态
        ResponseDto result = driverOpenFeign.updateDriverTakingStatus((int) order.getDriverId(), 2);
        System.out.println(result);
        if(result.getCode()!=1){
            return ResponseDto.ok("修改司机状态失败！");
        }
        //如果redis中存在"orderStar" + orderId如果这个订单是系统派单需要把redis中的订单状态修改为已接单
        if(redisTemplate.hasKey("orderStar"+orderId)){
            redisUtil.set("orderStar"+orderId,"1");
        }
        //如果redis中存在"driversOrder" + driverId 删除
        if(redisTemplate.hasKey("driversOrder" + driverId)){
            redisUtil.del("driversOrder" + driverId);
        }
        return ResponseDto.ok("抢单成功！");
    }

    @Override
    public List<TripOrder> orderList(int driverId) {
        //查找所有订单状态为待接单状态的订单
        LambdaQueryWrapper<TripOrder> wrapper=new LambdaQueryWrapper<TripOrder>()
                .eq(TripOrder::getOrderStatus,0)
                .eq(TripOrder::getDriverId,0);
        List<TripOrder> allList=orderMapper.selectList(wrapper);
//        System.out.println(allList);
        //  并且  该订单的打车类型为该司机车辆的类型
        //查找司机的类型
        ResponseDto result = driverOpenFeign.getDriverType(driverId);
//        System.out.println(result);
//        System.out.println(result.getData());
        Integer driverType = (Integer)result.getData();
        //可见订单列表
        List<TripOrder> orderList=new ArrayList<>();
        //获取订单支持的类型
        for (int i = 0; i < allList.size(); i++) {
            TripOrder order = allList.get(i);
            String carTypes = order.getCarTypes();
            List<Integer> typeList = JSON.parseArray(carTypes, Integer.class);
//            System.out.println(typeList);
            if(typeList.contains(driverType)){
                Map<String, String> map = JSON.parseObject(order.getCarPrices(),new TypeReference<Map<String, String>>() {});
//                System.out.println("-------------------------");
//                System.out.println(map);
//                System.out.println("-------------------------");
//                System.out.println(map.get(String.valueOf(driverType)));
                double price = Double.parseDouble(map.get(String.valueOf(driverType)));
                order.setPrice(price);
                orderList.add(order);
            }
        }
//        System.out.println(orderList);
        return orderList;
    }

    @Override
    public TripOrder confirmStart(Integer driverId) {
        //根据司机id和订单状态确保唯一订单，修改该订单的状态为进行中
        LambdaUpdateWrapper<TripOrder> updateWrapper=new LambdaUpdateWrapper<TripOrder>()
                .set(TripOrder::getOrderStatus,2)
                .eq(TripOrder::getDriverId,driverId)
                .eq(TripOrder::getOrderStatus,1);
        int i = orderMapper.update(updateWrapper);
        if(i<=0){
            return null;
        }
        //找到该订单并返回
        LambdaQueryWrapper<TripOrder> wrapper=new LambdaQueryWrapper<TripOrder>()
                .eq(TripOrder::getDriverId,driverId)
                .eq(TripOrder::getOrderStatus,2);
        TripOrder order = orderMapper.selectOne(wrapper);
        return order;
    }

    @Override
    public TripOrder confirmEnd(Integer driverId) {
        //到达目的地后，补充订单详情

        //根据司机id和订单状态获取订单
        //找到该订单并返回
        LambdaQueryWrapper<TripOrder> wrapper=new LambdaQueryWrapper<TripOrder>()
                .eq(TripOrder::getDriverId,driverId)
                .eq(TripOrder::getOrderStatus,2);
        TripOrder order = orderMapper.selectOne(wrapper);
        order.setCompleteTime(Timestamp.valueOf(LocalDateTime.now()));
        order.setOrderStatus(3);
        int i = orderMapper.updateById(order);
        if(i<=0){
            return null;
        }
        //修改司机的状态为空闲
        ResponseDto result = driverOpenFeign.updateDriverTakingStatus((int) order.getDriverId(), 1);
        System.out.println(result);
        if(result.getCode()!=1){
            log.error("修改司机状态失败！");
            return null;
        }
        return order;
    }

    @Override
    public OrderDriverDto selecetOrderAndDriver(long orderId) {
        System.out.println(orderMapper.selecetOrderAndDriver(orderId) + "    -4512");
        return orderMapper.selecetOrderAndDriver(orderId);
    }

    @Override
    public void deleteOrder(long orderId) {

        //修改订单状态
        LambdaUpdateWrapper<TripOrder> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(TripOrder::getOrderId,orderId)
                .set(TripOrder::getOrderState,2);
        orderMapper.update(wrapper);
        //删除redis中订单数量
        // 删除 Redis 中缓存的订单信息
        if(redisTemplate.hasKey(String.valueOf(orderId))){
            redisUtil.del(String.valueOf(orderId));
        }
        //删除redis中存储的订单状态
        if(redisTemplate.hasKey("driverList" + orderId)){
            redisUtil.del("driverList" + orderId);
        }
        //删除redis中存储的被拒单司机信息
        if(redisTemplate.hasKey("orderStar"+orderId)){
            redisUtil.del("orderStar"+orderId);
        }
    }

    @Override
    public ResponseDto driverInformation(long userId) {
        TripOrderDto tripOrderDto = orderMapper.driverInformation(userId);
        //System.out.println(tripOrderDto + " ----tripOrderDto");
        if(tripOrderDto==null){
            return ResponseDto.fail("查询接单司机失败！");
        }
        return ResponseDto.ok(tripOrderDto);
    }

    @Override
    public String isRob(long orderId) {

        String key = String.valueOf(orderId).trim();
        System.out.println(key);
        String s = redisUtil.get(key);

        System.out.println(s + " 订单状态");

        // 如果为空或不是"1"，表示未接单或不存在
        if ("1".equals(s)) {
            System.out.println("订单未接单");
            return "未接单";
        } else {
            System.out.println("订单已接单");
            return "已接单";
        }
    }

    @Override
    public List<OrderDto> selectAllOrderList(Integer driverId) {
        return orderMapper.selectOrderList(driverId,null);
    }

    @Override
    public List<OrderDto> selectWaitingOrderList(Integer driverId) {
        return orderMapper.selectOrderList(driverId,1);
    }

    @Override
    public List<OrderDto> selectOngoingOrderList(Integer driverId) {
        return orderMapper.selectOrderList(driverId,2);
    }

    @Override
    public List<OrderDto> selectCompletedOrderList(Integer driverId) {
        return orderMapper.selectOrderList(driverId,3);
    }

    @Override
    public List<OrderDto> selectSystemOrderList(Integer driverId) {
        return orderMapper.selectOrderList(driverId,0);
    }

    @Override
    public List<OrderDto> selectPassengerAllOrderList(Integer userId) {
        return orderMapper.selectPassengerOrderList(userId,null,null);
    }

    @Override
    public List<OrderDto> selectPassengerPendingPaymentOrderList(Integer userId) {
        return orderMapper.selectPassengerOrderList(userId,3,1);
    }

    @Override
    public List<OrderDto> selectPassengerCancelOrderList(Integer userId) {
        return orderMapper.selectPassengerOrderList(userId,4,0);
    }

    @Override
    public List<OrderDto> selectPassengerCompleteOrderList(Integer userId) {
        return orderMapper.selectPassengerOrderList(userId,3,null);
    }

    @Override
    public List<OrderDto> selectPassengerWaitingOrderList(Integer userId) {
        List<Integer> integers = new ArrayList<>();
        integers.add(0);
        integers.add(1);
        return orderMapper.selectPassengerOrderListStatusList(userId,integers,0);
    }

    @Override
    public ResponseDto cancelOrder(TripOrder tripOrder) {
        TripOrder order = orderMapper.selectById(tripOrder.getOrderId());
        if(order==null){
            return ResponseDto.fail("订单有误！");
        }
        //必须已接单中或还没司机抢单的订单才可以取消
        if(order.getOrderStatus()!=1 && order.getOrderStatus()!=0){
            return ResponseDto.fail("订单状态有误！");
        }
        //修改订单状态
        order.setOrderStatus(4);
        int i = orderMapper.updateById(order);
        if(i<=0){
            return ResponseDto.fail("取消失败！");
        }
        //修改司机的状态为空闲
        ResponseDto result = driverOpenFeign.updateDriverTakingStatus((int) order.getDriverId(), 1);
        System.out.println(result);
        if(result.getCode()!=1){
            return ResponseDto.ok("修改司机状态失败！");
        }
        return ResponseDto.ok("取消成功！");
    }

    @Override
    public ResponseDto rejectOrder(TripOrder order) {
        //从Redis查找今日拒单次数，若没有生成一个。
        long driverId = order.getDriverId();
        //每日拒接数
        Long count= 0L;
        //获取今日日期
        String date = LocalDate.now(ZoneId.of("Asia/Shanghai")).toString().replace("-", "");
        //拼接key
        String key="RejectOrder-"+driverId+"-"+date;
//        System.out.println("KEY："+key);
        count = redisTemplate.opsForValue().increment(key);
        if(count>=6){
            return ResponseDto.fail("拒单上限！");
        }
//        System.out.println("今日拒单次数："+count);
        if(count==1){
            //计算今天到明天的时间差
            LocalDate tomorrow = LocalDate.now(ZoneId.of("Asia/Shanghai")).plusDays(1);
            long expireTime = tomorrow.atStartOfDay(ZoneId.of("Asia/Shanghai")).toEpochSecond() - System.currentTimeMillis() / 1000;

            //设置过期时间
            redisTemplate.expire(key,expireTime, TimeUnit.SECONDS);
        }

        //创建redis
        redisTemplate.opsForSet().add("driverList" + order.getOrderId(),String.valueOf(driverId));

        //如果redis中存在"driversOrder" + driverId 删除
        if(redisTemplate.hasKey("driversOrder" + driverId)){
            redisUtil.del("driversOrder" + driverId);
        }

        ResponseDto responseDto = driverOpenFeign.automaticOrder(driverId);
        return responseDto;
    }

    @Override
    public List<OrderDto> selectCompleteThePayment(Integer userId) {
        return orderMapper.selectPassengerOrderList(userId,3,1);
    }

    @Override
    public List<OrderDto> selectCompletedUnpaid(Integer userId) {
        return orderMapper.selectPassengerOrderList(userId,3,0);
    }

}
